#include "../logs/mylog.h"
#include <chrono>

void benchmark(const string &logger_name, size_t thr_count, size_t msg_count, size_t msg_len)
{
    //获取日志器
    mylog::Logger::ptr logger = mylog::getLogger(logger_name);
    if (logger == nullptr)
    {
        return ;
    }
    cout << "测试日志数量：" << msg_count << "条，总大小：" << (msg_count * msg_len) / 1024 << "KB" << endl;
    //组织指定长度的日志消息
    string msg(msg_len-1, 'A');//留一个字节给'\n'
    //创建指定数量的线程
    vector<std::thread> threads;
    vector<double> cost_arry(thr_count);
    size_t msg_per_thr = msg_count / thr_count;//每个线程要输出的日志消息数量
    for (int i = 0; i < thr_count; ++i)
    {
        threads.emplace_back([&, i]()
        {
            //从线程函数内部开始计时
            auto star = std::chrono::high_resolution_clock::now();
            //开始循环写日志
            for(int j = 0; j < msg_per_thr; ++j)
            {
                logger->fatal("%s", msg.c_str());
            }
            //结束计时
            auto end = std::chrono::high_resolution_clock::now();
            std::chrono::duration<double> cost = end - star;
            cost_arry[i] = cost.count();
            cout << "线程" << i << ":" << "\t输出" << msg_per_thr << "条日志，" << "耗时：" << cost_arry[i] << "s" << endl;
        });
    }
    for (int i = 0; i < thr_count; ++i)
    {
        threads[i].join();
    }
    //计算总耗时：在多线程中，因为多个线程是并发（同时）运行的，所以总耗时就是耗时最大的那个线程所用时间
    double max_cost = cost_arry[0];
    for (int i = 0; i < thr_count; ++i)
    {
        max_cost = cost_arry[i] > max_cost ? cost_arry[i] : max_cost;
    }
    size_t msg_per_sec = msg_count / max_cost;
    size_t size_per_sec = (msg_count * msg_len) / (max_cost * 1024);
    //进行输出打印
    cout << "\t总耗时：" << max_cost << "s" << endl;
    cout << "\t每秒输出日志数量：" << msg_per_sec << "条" << endl;
    cout << "\t每秒输出日志大小：" << size_per_sec << "KB" << endl;
}

void sync_benchmark()
{
    std::unique_ptr<mylog::LoggerBuilder> builder(new mylog::GlobalLoggerBuilder());
    builder->buildLoggerName("sync_logger");
    builder->buildLoggerType(mylog::LoggerType::LOGGER_SYNC);
    builder->buildFormatter("%m%n");
    builder->buildSink<mylog::FileSink>("./logfile/sync.log");
    builder->build();
    benchmark("sync_logger", 3, 1000000, 100);
}

void async_benchmark()
{
    std::unique_ptr<mylog::LoggerBuilder> builder(new mylog::GlobalLoggerBuilder());
    builder->buildLoggerName("async_logger");
    builder->buildLoggerType(mylog::LoggerType::LOGGER_ASYNC);
    builder->buildFormatter("%m%n");
    builder->buildEnableUnSafeAsync();//开起非安全模式--主要是为了将实际落地时间排除在外
    builder->buildSink<mylog::FileSink>("./logfile/async.log");
    builder->build();
    benchmark("async_logger", 5, 2000000, 100);
}

int main()
{
    //sync_benchmark();
    async_benchmark();
    return 0;
}